Retirado do artigo Miller et al. (2019). Distance sampling in R. Journal of Statistical Sofware 89(1)

Formatação do conjunto de dados

Variáveis necessárias para o data.frame:

Transectos que foram amostrados, mas que não tiveram observações (n = 0) devem ser incluídos no conjunto de dados com NA nas observações de distância e qualquer outra covariael para a qual não se tenha observação.

# cutia_tap_arap |> 
#   complete(Region.Label, Sample.Label, sp_name) |> 
#   datatable(filter = list(position = "top"))

Jogar a imputacao de NAs pra dentro da funcao carregar dados completos.

Determinando a distância para truncar os dados

# desenha o grafico com a distribuicao de distancias perpendiculares
cutia_tap_arap |> 
  plotar_distribuicao_distancia_interativo()
Warning: Continuous y aesthetic
ℹ did you forget `aes(group = ...)`?

Ajustando funções de detecção no R

Cutias da Resex Tapajós-Arapiuns

Half-Normal sem termos de ajuste

Ajustando um modelo ao dados das cutias Dasyprocta croconota, configurando uma distância limite de 20m e usando Half-normal como key function usando o argumento key, sem termo de ajuste.

# ajustando a função de detecção para uma distancia de truncamento de 20 metros
# Key function - Half-normal 
cutia_tap_arap_hn <- cutia_tap_arap |> 
  ds(
    truncation = 20,
    key = "hn",
    adjustment = NULL
  )
Fitting half-normal key function
AIC= 7227.642
Warning: Some observations not included in the analysis

Half-Normal com termos de ajuste Hermite-Polynomial

Ajustando um modelo ao dados das cutias Dasyprocta croconota, configurando uma distância limite de 20m e usando Half-normal como key function usando o argumento key, com termo de ajuste do tipo Hermite-polynomial.

# ajustando a função de detecção para uma distancia de truncamento de 20 metros
# Key function - Half-normal 
cutia_tap_arap_hn_herm <- cutia_tap_arap |> 
  ds(
    truncation = 20,
    key = "hn",
    adjustment = "herm"
  )
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 7227.642
Fitting half-normal key function with Hermite(4) adjustments
AIC= 7229.142

Half-normal key function selected.
Warning: Some observations not included in the analysis

Half-Normal com termos de ajuste Cosine

Ajustando um modelo ao dados das cutias Dasyprocta croconota, configurando uma distância limite de 20m e usando Half-normal como key function usando o argumento key, com termo de ajuste do tipo Cosine.

# ajustando a função de detecção para uma distancia de truncamento de 20 metros
# Key function - Half-normal 
cutia_tap_arap_hn_cos <- cutia_tap_arap |> 
  ds(
    truncation = 20,
    key = "hn"
    )
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 7227.642
Fitting half-normal key function with cosine(2) adjustments
AIC= 7207.469
Fitting half-normal key function with cosine(2,3) adjustments
AIC= 7201.248
Fitting half-normal key function with cosine(2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 7152.177
Fitting half-normal key function with cosine(2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 7146.681
Fitting half-normal key function with cosine(2,3,4,5,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 7129.427
Warning: Detection function is not strictly monotonic!Warning: Some observations not included in the analysis

Hazard-Rate sem termos de ajuste

Ajustando um modelo ao dados da cutia Dasyprocta croconota, configurando uma distância limite de 20m e usando Hazard rate como key function usando o argumento key.

# Key function - Hazard-rate 
cutia_tap_arap_hr <- cutia_tap_arap |> 
  ds(
    truncation = 20,
     key = "hr",
    adjustment = NULL
  )
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 6907.541
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Some observations not included in the analysis

Hazard-Rate com termos de ajuste Simple-polynomial

Ajustando um modelo ao dados da cutia Dasyprocta croconota, configurando uma distância limite de 20m e usando Hazard rate como key function usando o argumento key e termo de ajuste do tipo polinomial simples.

# Key function - Hazard-rate 
cutia_tap_arap_hr_poly <- cutia_tap_arap |> 
  ds(
    truncation = 20,
     key = "hr",
    adjustment = "poly"
  )
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 6907.541
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Some observations not included in the analysis

Hazard-Rate com termos de ajuste Cosine

Ajustando um modelo ao dados da cutia Dasyprocta croconota, configurando uma distância limite de 20m e usando Hazard rate como key function usando o argumento key e termo de ajuste do tipo cosseno.

# Key function - Hazard-rate 
cutia_tap_arap_hr_cos <- cutia_tap_arap |> 
  ds(
    truncation = 20,
    key = "hr"
    )
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 6907.541
Fitting hazard-rate key function with cosine(2) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Some observations not included in the analysis
plot(cutia_tap_arap_hn, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hn_herm, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hn_cos, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hr, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hr_poly, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hr_cos, breaks = seq(0, 20, 2.5))

Ajustando um modelo ao dados das cutias, configurando uma distância limite de 20m e usando Uniform como key function a séria de ajuste com o argumento adjustment ee especificando a ordem com o argumento order.

cutia_unifcos <- cutia_tap_arap |> 
  ds(truncation = 20,
     key = "unif",
     adjustment = "cos",
     order = c(1, 2))

Ajuste Hermite pollynomial usa od código "herm" e polinomial simples "poly".

Podemos incluir covariáveis utilizando o argumento formula = ~ .... Abaixo, está especificado um modelo “Hazard-rate” para os dados de cutia q ue inclui o tempo de senso como covariável e uma distância limite de 20m.

cutia_hr_time <- cutia_tap_arap_15 |> 
  ds(truncation = 20,
     key = "hr",
     formula = ~ cense_time)

Adicionando uma segunda covariável: tamanho do grupo.

cutia_hr_time_size <- ds(data = cutia_tap_arap_15,
                     truncation = 20,
                     transect = "line",
                     key = "hr",
                     formula = ~ cense_time + size)
plot(cutia_hr_time)
plot(cutia_hr_time_size)

Checagem e seleção de modelos

Podemos usar a função summary para obter informações importantes sobre o modelo.

summary(cutia_hn)

O resultado inclui detalhes sobre o dado e a especificação do modelo, assim como dos coeficientes (\(\beta_{j}\)) e sua inceteza, a média do valor de detectabilidade e sua incerteza e uma estimativa da abundância na área coberta pela amostragem (sem levar em consideração o tamanho dos agrupamentos, ou bandos).

Bondade de ajuste

Para visualizar quão bem a função de detecção se ajusta aos dados quanto temos as distâncias exatas podemos usar um plot de quantis empíricos x teóricos (Q-Q plot). Ele compara a função de distribuição cumulativa (CDF) dos valores ajustados da função detecção a distribuição empírica dos dados (EDF).

Também podemos usar o teste de Cramér-von Mises para testar se os pontos da EDF e da CDF tem origem na mesma distribuição. O teste usa a soma de todas as distâncias entre um ponto e a linha y = x para formar a estatística a ser testada. Um resultado significativo fornece evidência contra a hiipótese nula, sugerindo que o modelo não se ajusta bem aos dados.

# ajustando um modelo Half-normal
cutia_hn <- ds(data = cutia_tap_arap_15,
                 truncation = 20,
                 transect = "line",
                 key = "hn", 
                 adjustment = NULL)

# conduzindo o teste dfe bondadede ajuste de Cramer-von Mises
gof_ds(cutia_hn)

gof_ds(cutia_hr_time)

O resutlado do teste aponta que o modelo Half-normal deve ser descartado.

Testes de bondade de ajuste de chi-quadrado são gerados usando a função gof_ds quando as distâncias forneceidas estão categorizadas.

Seleção de Modelos

Uma vez que temos um conjunto de modelos plausíveis, podemos utilizar o cirtériode informaçãode Akaike (AIC) para selecionar entre os modelos o que melhor se ajusta aos dados utilizando a função summarize_ds_models.

# gerando uma tabela de seleção de modelos usando AIC
summarize_ds_models(cutia_hn, cutia_hr_time, cutia_hr_time_size)

O melhor modelo é o Hazard-rate com tempo de senso e tamanho do grupo como covariáveis.

Estimando a abundância e a variância

Estimando abundância e variância no R

Para obter a abundância na região de estudo, primeiro calculamos a abundância na área amostrada para obter \(N_c\) e em seguida escalonamos esse valor para toda a área de estudo multiplicando \(N_c\) pela razão entre a área amostrada e a área da região. Para estimar a abundância na área amostrada, utilizamos as estimativas de probabilidade de detecção no estimador de Horvitz-Thompson.

Quando fornecemos os dados no formato correto (“flatfile”) ds irá automaticamente calcular as estimativas de abundância baseado nas informações de amostragem presenta nos dados.

summary(cutia_hn)
  1. Summary statistics: fornece as áreas, aŕea de amostragem, esforço, número de observações, número de transectos, taxa de encontro, seus erros padrões e coeficientes de variação para cada estrato;

  2. Abundance: fornece estimativas, erros padrões, coeficientesde variação, intervalos de confiança inferior e superior, graus de liberdade para a estimativa de abundância de cada estrato;

  3. Densidade: lista as mesmas estatísticas de Abundance, só que para densidade.

LS0tCnRpdGxlOiAiRGlzdGFuY2Ugbm8gUiBjb20gZGFkb3MgJ21vZGVsbyciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClJldGlyYWRvIGRvIGFydGlnbyBNaWxsZXIgZXQgYWwuICgyMDE5KS4gRGlzdGFuY2Ugc2FtcGxpbmcgaW4gUi4gSm91cm5hbCBvZiBTdGF0aXN0aWNhbCBTb2Z3YXJlIDg5KDEpCgpgYGB7ciBzZXR1cH0KIyBpbnN0YWxhciBwYWNvdGVzIG5lY2Vzc8OhcmlvcwojaW5zdGFsbC5wYWNrYWdlcygiRGlzdGFuY2UiKQoKIyBpbnN0YWxhciBwYWNvdGVzIGFkaWNpb25haXMKI2luc3RhbGwucGFja2FnZXMoIm1yZHMiKQojaW5zdGFsbC5wYWNrYWdlcygiZHNtIikKI2luc3RhbGwucGFja2FnZXMoIm1hZHMiKQojaW5zdGFsbC5wYWNrYWdlcygiZHNpbXMiKQoKIyBjYXJyZWdhciBwYWNvdGVzIApsaWJyYXJ5KERpc3RhbmNlKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KERUKQpsaWJyYXJ5KGZsZXh0YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHRpZHlyKQoKIyBjYXJyZWdhciBhcyBmdW7Dp8O1ZXMgZGEgcGFzdGEgUgojIGNhcnJlZ2FyIGZ1bsOnw6NvIHNjcmlwdF9jYXJyZWdhcl9mdW7Dp8O1ZXNfcGFzdGFfci5SCnNvdXJjZSgKICBwYXN0ZTAoCiAgICBoZXJlOjpoZXJlKCksCiAgICAiL1IvbWluaGFzX2Z1bmNvZXMuUiIKICApCikKCiMgY2FycmVnYXIgZGFkb3MKY3V0aWFfdGFwX2FyYXAgPC0gdHJhbnNmb3JtYXJfcGFyYV9kaXN0YW5jZVJfY292YXJpYXZlaXMoKSB8PiAKICBmaWx0ZXIoCiAgICB1Y19uYW1lID09ICJSZXNleCBUYXBham9zLUFyYXBpdW5zIiwKICAgIHNwX25hbWUgPT0gIkRhc3lwcm9jdGEgY3JvY29ub3RhIgogICkgfD4gCiAgZHJvcF9uYShkaXN0YW5jZSkKICAKIyByZWFkcjo6d3JpdGVfZXhjZWxfY3N2KAojICAgY3V0aWFfdGFwX2FyYXAsIAojICAgcGFzdGUwKAojICAgICBoZXJlOjpoZXJlKCksIAojICAgICAiL2RhdGEvY3V0aWFfdGFwX2FyYXAuY3N2IgojICAgKQojICkKCmN1dGlhX3RhcF9hcmFwIHw+IAogIERUOjpkYXRhdGFibGUoZmlsdGVyID0gInRvcCIpCmBgYAoKIyBGb3JtYXRhw6fDo28gZG8gY29uanVudG8gZGUgZGFkb3MKClZhcmnDoXZlaXMgbmVjZXNzw6FyaWFzIHBhcmEgbyBgZGF0YS5mcmFtZWA6CgotIGBSZWdpb24uTGFiZWxgOiB2ZXRvciBmYXRvciBjb20gbyBlc3RyYXRvIGNvbnRlbmRvIG8gdHJhbnNlY3RvIChwb2RlIHNlciB1bWEgZXN0cmF0aWZpY2HDp8OjbyBwcsOpLWFtb3N0cmFnZW0gLSBVQ3MgLSBvdSBww7NzLWFtb3N0cmFnZW0gLSBleC4gcmVnacOjbywgZXN0YWRvLCBiaW9tYSkKCi0gYEFyZWFgOiB2ZXRvciBudW3DqXJpY28gY29udGVuZG8gYSDDoXJlYSBkbyBlc3RyYXRvOwoKLSBgU2FtcGxlLkxhYmVsYDogdmV0b3IgbsO6bWVyaWNvIGNvbnRlbmRvIGEgaWRlbnRpZGFkZSAoSUQpIGRvIHRyYW5zZWN0bwoKLSBgb2JqZWN0YDogbm9tZSBhZGljaW9uYWwsIHZlciBzZcOnw6NvIDY7CgotIGBkZXRlY3RlZGA6IG5vbWUgYWRpY2lvbmFsLCB2ZXIgc2XDp8OjbyA2OwoKLSBgRWZmb3J0YDogdmV0b3IgbsO6bWVyaWNvIGNvbnRlbmRvIG8gZXNmb3LDp28gZG8gdHJhbnNlY3RvIChwYXJhIGxpbmhhcyBzZXUgY29tcHJpbWVudG8sIHBhcmEgcG9udG9zIG8gbsO6bWVybyBkZSB2ZXplcyBxdWUgbyBwb250byBmb2kgdmlzaXRhZG8pCgotIGBzaXplYDogdmV0b3IgbnVtw6lyaWNvIGNvcG50ZW5kbyBvIHRhbWFuaG8gZG8gZ3J1cG8gb2JzZXJ2YWRvOwoKLSBgZGlzdGFuY2VgOiB2ZXRvciBudW3DqXJpY28gZGUgZGlzdMOibmNpYXMgb2JzZXJ2YWRhczsKCi0gYE1vbnRoYDoKCi0gYE9Cc2A6CgotIGBTcGA6CgogLSBgbWFzYDoKIAogLSBgSEFTYDoKIAogLSBgU3R1ZHkuQXJlYWA6CiAKVHJhbnNlY3RvcyBxdWUgZm9yYW0gYW1vc3RyYWRvcywgbWFzIHF1ZSBuw6NvIHRpdmVyYW0gb2JzZXJ2YcOnw7VlcyAobiA9IDApIGRldmVtIHNlciBpbmNsdcOtZG9zIG5vIGNvbmp1bnRvIGRlIGRhZG9zIGNvbSBgTkFgIG5hcyBvYnNlcnZhw6fDtWVzIGRlIGRpc3TDom5jaWEgZSBxdWFscXVlciBvdXRyYSBjb3ZhcmlhZWwgcGFyYSBhIHF1YWwgbsOjbyBzZSB0ZW5oYSBvYnNlcnZhw6fDo28uCiAKYGBge3J9CiMgY3V0aWFfdGFwX2FyYXAgfD4gCiMgICBjb21wbGV0ZShSZWdpb24uTGFiZWwsIFNhbXBsZS5MYWJlbCwgc3BfbmFtZSkgfD4gCiMgICBkYXRhdGFibGUoZmlsdGVyID0gbGlzdChwb3NpdGlvbiA9ICJ0b3AiKSkKYGBgCgpKb2dhciBhIGltcHV0YWNhbyBkZSBgTkFgcyBwcmEgZGVudHJvIGRhIGZ1bmNhbyBjYXJyZWdhciBkYWRvcyBjb21wbGV0b3MuCgojIyBEZXRlcm1pbmFuZG8gYSBkaXN0w6JuY2lhIHBhcmEgdHJ1bmNhciBvcyBkYWRvcwoKYGBge3IsIGZpZy5oZWlnaHQ9MTUsIGZpZy53aWR0aD0xMCwgd2FybmluZz1GQUxTRX0KIyBkZXNlbmhhIG8gZ3JhZmljbyBjb20gYSBkaXN0cmlidWljYW8gZGUgZGlzdGFuY2lhcyBwZXJwZW5kaWN1bGFyZXMKY3V0aWFfdGFwX2FyYXAgfD4gCiAgcGxvdGFyX2Rpc3RyaWJ1aWNhb19kaXN0YW5jaWFfaW50ZXJhdGl2bygpCmBgYAoKIAojIyBBanVzdGFuZG8gZnVuw6fDtWVzIGRlIGRldGVjw6fDo28gbm8gUgoKIyMjIEN1dGlhcyBkYSBSZXNleCBUYXBhasOzcy1BcmFwaXVucwoKIyMjIyAqSGFsZi1Ob3JtYWwqIHNlbSB0ZXJtb3MgZGUgYWp1c3RlCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhcyBjdXRpYXMgKkRhc3lwcm9jdGEgY3JvY29ub3RhKiwgY29uZmlndXJhbmRvIHVtYSBkaXN0w6JuY2lhIGxpbWl0ZSBkZSAyMG0gZSB1c2FuZG8gKkhhbGYtbm9ybWFsKiBjb21vICprZXkgZnVuY3Rpb24qIHVzYW5kbyBvIGFyZ3VtZW50byBga2V5YCwgc2VtIHRlcm1vIGRlIGFqdXN0ZS4KCmBgYHtyfQojIGFqdXN0YW5kbyBhIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gcGFyYSB1bWEgZGlzdGFuY2lhIGRlIHRydW5jYW1lbnRvIGRlIDIwIG1ldHJvcwojIEtleSBmdW5jdGlvbiAtIEhhbGYtbm9ybWFsIApjdXRpYV90YXBfYXJhcF9obiA8LSBjdXRpYV90YXBfYXJhcCB8PiAKICBkcygKICAgIHRydW5jYXRpb24gPSAyMCwKICAgIGtleSA9ICJobiIsCiAgICBhZGp1c3RtZW50ID0gTlVMTAogICkKYGBgCgojIyMjICpIYWxmLU5vcm1hbCogY29tIHRlcm1vcyBkZSBhanVzdGUgKkhlcm1pdGUtUG9seW5vbWlhbCoKCkFqdXN0YW5kbyB1bSBtb2RlbG8gYW8gZGFkb3MgZGFzIGN1dGlhcyAqRGFzeXByb2N0YSBjcm9jb25vdGEqLCBjb25maWd1cmFuZG8gdW1hIGRpc3TDom5jaWEgbGltaXRlIGRlIDIwbSBlIHVzYW5kbyAqSGFsZi1ub3JtYWwqIGNvbW8gKmtleSBmdW5jdGlvbiogdXNhbmRvIG8gYXJndW1lbnRvIGBrZXlgLCBjb20gdGVybW8gZGUgYWp1c3RlIGRvIHRpcG8gKkhlcm1pdGUtcG9seW5vbWlhbCouCgpgYGB7cn0KIyBhanVzdGFuZG8gYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIHBhcmEgdW1hIGRpc3RhbmNpYSBkZSB0cnVuY2FtZW50byBkZSAyMCBtZXRyb3MKIyBLZXkgZnVuY3Rpb24gLSBIYWxmLW5vcm1hbCAKY3V0aWFfdGFwX2FyYXBfaG5faGVybSA8LSBjdXRpYV90YXBfYXJhcCB8PiAKICBkcygKICAgIHRydW5jYXRpb24gPSAyMCwKICAgIGtleSA9ICJobiIsCiAgICBhZGp1c3RtZW50ID0gImhlcm0iCiAgKQpgYGAKCiMjIyMgKkhhbGYtTm9ybWFsKiBjb20gdGVybW9zIGRlIGFqdXN0ZSAqQ29zaW5lKgoKQWp1c3RhbmRvIHVtIG1vZGVsbyBhbyBkYWRvcyBkYXMgY3V0aWFzICpEYXN5cHJvY3RhIGNyb2Nvbm90YSosIGNvbmZpZ3VyYW5kbyB1bWEgZGlzdMOibmNpYSBsaW1pdGUgZGUgMjBtIGUgdXNhbmRvICpIYWxmLW5vcm1hbCogY29tbyAqa2V5IGZ1bmN0aW9uKiB1c2FuZG8gbyBhcmd1bWVudG8gYGtleWAsIGNvbSB0ZXJtbyBkZSBhanVzdGUgZG8gdGlwbyAqQ29zaW5lKi4KCmBgYHtyfQojIGFqdXN0YW5kbyBhIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gcGFyYSB1bWEgZGlzdGFuY2lhIGRlIHRydW5jYW1lbnRvIGRlIDIwIG1ldHJvcwojIEtleSBmdW5jdGlvbiAtIEhhbGYtbm9ybWFsIApjdXRpYV90YXBfYXJhcF9obl9jb3MgPC0gY3V0aWFfdGFwX2FyYXAgfD4gCiAgZHMoCiAgICB0cnVuY2F0aW9uID0gMjAsCiAgICBrZXkgPSAiaG4iCiAgICApCmBgYAoKIyMjIyAqSGF6YXJkLVJhdGUqIHNlbSB0ZXJtb3MgZGUgYWp1c3RlCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhIGN1dGlhICpEYXN5cHJvY3RhIGNyb2Nvbm90YSosIGNvbmZpZ3VyYW5kbyB1bWEgZGlzdMOibmNpYSBsaW1pdGUgZGUgMjBtIGUgdXNhbmRvICpIYXphcmQgcmF0ZSogY29tbyAqa2V5IGZ1bmN0aW9uKiB1c2FuZG8gbyBhcmd1bWVudG8gYGtleWAuCgpgYGB7cn0KIyBLZXkgZnVuY3Rpb24gLSBIYXphcmQtcmF0ZSAKY3V0aWFfdGFwX2FyYXBfaHIgPC0gY3V0aWFfdGFwX2FyYXAgfD4gCiAgZHMoCiAgICB0cnVuY2F0aW9uID0gMjAsCiAgICAga2V5ID0gImhyIiwKICAgIGFkanVzdG1lbnQgPSBOVUxMCiAgKQpgYGAKCiMjIyMgKkhhemFyZC1SYXRlKiBjb20gdGVybW9zIGRlIGFqdXN0ZSAqU2ltcGxlLXBvbHlub21pYWwqCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhIGN1dGlhICpEYXN5cHJvY3RhIGNyb2Nvbm90YSosIGNvbmZpZ3VyYW5kbyB1bWEgZGlzdMOibmNpYSBsaW1pdGUgZGUgMjBtIGUgdXNhbmRvICpIYXphcmQgcmF0ZSogY29tbyAqa2V5IGZ1bmN0aW9uKiB1c2FuZG8gbyBhcmd1bWVudG8gYGtleWAgZSB0ZXJtbyBkZSBhanVzdGUgZG8gdGlwbyBwb2xpbm9taWFsIHNpbXBsZXMuCgpgYGB7cn0KIyBLZXkgZnVuY3Rpb24gLSBIYXphcmQtcmF0ZSAKY3V0aWFfdGFwX2FyYXBfaHJfcG9seSA8LSBjdXRpYV90YXBfYXJhcCB8PiAKICBkcygKICAgIHRydW5jYXRpb24gPSAyMCwKICAgICBrZXkgPSAiaHIiLAogICAgYWRqdXN0bWVudCA9ICJwb2x5IgogICkKYGBgCgojIyMjICpIYXphcmQtUmF0ZSogY29tIHRlcm1vcyBkZSBhanVzdGUgKkNvc2luZSoKCkFqdXN0YW5kbyB1bSBtb2RlbG8gYW8gZGFkb3MgZGEgY3V0aWEgKkRhc3lwcm9jdGEgY3JvY29ub3RhKiwgY29uZmlndXJhbmRvIHVtYSBkaXN0w6JuY2lhIGxpbWl0ZSBkZSAyMG0gZSB1c2FuZG8gKkhhemFyZCByYXRlKiBjb21vICprZXkgZnVuY3Rpb24qIHVzYW5kbyBvIGFyZ3VtZW50byBga2V5YCBlIHRlcm1vIGRlIGFqdXN0ZSBkbyB0aXBvIGNvc3Nlbm8uCgpgYGB7cn0KIyBLZXkgZnVuY3Rpb24gLSBIYXphcmQtcmF0ZSAKY3V0aWFfdGFwX2FyYXBfaHJfY29zIDwtIGN1dGlhX3RhcF9hcmFwIHw+IAogIGRzKAogICAgdHJ1bmNhdGlvbiA9IDIwLAogICAga2V5ID0gImhyIgogICAgKQpgYGAKCgpgYGB7cn0KcGxvdChjdXRpYV90YXBfYXJhcF9obiwgYnJlYWtzID0gc2VxKDAsIDIwLCAyLjUpKQpwbG90KGN1dGlhX3RhcF9hcmFwX2huX2hlcm0sIGJyZWFrcyA9IHNlcSgwLCAyMCwgMi41KSkKcGxvdChjdXRpYV90YXBfYXJhcF9obl9jb3MsIGJyZWFrcyA9IHNlcSgwLCAyMCwgMi41KSkKcGxvdChjdXRpYV90YXBfYXJhcF9ociwgYnJlYWtzID0gc2VxKDAsIDIwLCAyLjUpKQpwbG90KGN1dGlhX3RhcF9hcmFwX2hyX3BvbHksIGJyZWFrcyA9IHNlcSgwLCAyMCwgMi41KSkKcGxvdChjdXRpYV90YXBfYXJhcF9ocl9jb3MsIGJyZWFrcyA9IHNlcSgwLCAyMCwgMi41KSkKYGBgCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhcyBjdXRpYXMsIGNvbmZpZ3VyYW5kbyB1bWEgZGlzdMOibmNpYSBsaW1pdGUgZGUgMjBtIGUgdXNhbmRvICpVbmlmb3JtKiBjb21vICprZXkgZnVuY3Rpb24qIGEgc8OpcmlhIGRlIGFqdXN0ZSBjb20gbyBhcmd1bWVudG8gYGFkanVzdG1lbnRgIGVlIGVzcGVjaWZpY2FuZG8gYSBvcmRlbSBjb20gbyBhcmd1bWVudG8gYG9yZGVyYC4KCmBgYHtyfQpjdXRpYV91bmlmY29zIDwtIGN1dGlhX3RhcF9hcmFwIHw+IAogIGRzKHRydW5jYXRpb24gPSAyMCwKICAgICBrZXkgPSAidW5pZiIsCiAgICAgYWRqdXN0bWVudCA9ICJjb3MiLAogICAgIG9yZGVyID0gYygxLCAyKSkKYGBgCgpBanVzdGUgKkhlcm1pdGUgcG9sbHlub21pYWwqIHVzYSBvZCBjw7NkaWdvIGAiaGVybSJgIGUgcG9saW5vbWlhbCBzaW1wbGVzIGAicG9seSJgLgoKUG9kZW1vcyBpbmNsdWlyIGNvdmFyacOhdmVpcyB1dGlsaXphbmRvIG8gYXJndW1lbnRvIGBmb3JtdWxhID0gfiAuLi5gLiBBYmFpeG8sIGVzdMOhIGVzcGVjaWZpY2FkbyB1bSBtb2RlbG8gIkhhemFyZC1yYXRlIiBwYXJhIG9zIGRhZG9zIGRlIGN1dGlhIHEgdWUgaW5jbHVpIG8gdGVtcG8gZGUgc2Vuc28gY29tbyBjb3ZhcmnDoXZlbCBlIHVtYSBkaXN0w6JuY2lhIGxpbWl0ZSBkZSAyMG0uCgpgYGB7cn0KY3V0aWFfaHJfdGltZSA8LSBjdXRpYV90YXBfYXJhcF8xNSB8PiAKICBkcyh0cnVuY2F0aW9uID0gMjAsCiAgICAga2V5ID0gImhyIiwKICAgICBmb3JtdWxhID0gfiBjZW5zZV90aW1lKQpgYGAKCkFkaWNpb25hbmRvIHVtYSBzZWd1bmRhIGNvdmFyacOhdmVsOiB0YW1hbmhvIGRvIGdydXBvLgoKYGBge3J9CmN1dGlhX2hyX3RpbWVfc2l6ZSA8LSBkcyhkYXRhID0gY3V0aWFfdGFwX2FyYXBfMTUsCiAgICAgICAgICAgICAgICAgICAgIHRydW5jYXRpb24gPSAyMCwKICAgICAgICAgICAgICAgICAgICAgdHJhbnNlY3QgPSAibGluZSIsCiAgICAgICAgICAgICAgICAgICAgIGtleSA9ICJociIsCiAgICAgICAgICAgICAgICAgICAgIGZvcm11bGEgPSB+IGNlbnNlX3RpbWUgKyBzaXplKQpgYGAKCmBgYHtyfQpwbG90KGN1dGlhX2hyX3RpbWUpCnBsb3QoY3V0aWFfaHJfdGltZV9zaXplKQpgYGAKCiMjIENoZWNhZ2VtIGUgc2VsZcOnw6NvIGRlIG1vZGVsb3MKClBvZGVtb3MgdXNhciBhIGZ1bsOnw6NvIGBzdW1tYXJ5YCBwYXJhIG9idGVyIGluZm9ybWHDp8O1ZXMgaW1wb3J0YW50ZXMgc29icmUgbyBtb2RlbG8uCgpgYGB7cn0Kc3VtbWFyeShjdXRpYV9obikKYGBgCgpPIHJlc3VsdGFkbyAgaW5jbHVpIGRldGFsaGVzIHNvYnJlIG8gZGFkbyBlIGEgZXNwZWNpZmljYcOnw6NvIGRvIG1vZGVsbywgYXNzaW0gY29tbyBkb3MgY29lZmljaWVudGVzICgkXGJldGFfe2p9JCkgZSBzdWEgaW5jZXRlemEsIGEgbcOpZGlhIGRvIHZhbG9yIGRlIGRldGVjdGFiaWxpZGFkZSBlIHN1YSBpbmNlcnRlemEgZSB1bWEgZXN0aW1hdGl2YSBkYSBhYnVuZMOibmNpYSBuYSDDoXJlYSBjb2JlcnRhIHBlbGEgYW1vc3RyYWdlbSAoc2VtIGxldmFyIGVtIGNvbnNpZGVyYcOnw6NvIG8gdGFtYW5obyBkb3MgYWdydXBhbWVudG9zLCBvdSBiYW5kb3MpLiAKCiMjIyBCb25kYWRlIGRlIGFqdXN0ZQoKUGFyYSB2aXN1YWxpemFyIHF1w6NvIGJlbSBhIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gc2UgYWp1c3RhIGFvcyBkYWRvcyBxdWFudG8gdGVtb3MgYXMgZGlzdMOibmNpYXMgZXhhdGFzIHBvZGVtb3MgdXNhciB1bSBwbG90IGRlIHF1YW50aXMgZW1ww61yaWNvcyB4IHRlw7NyaWNvcyAoUS1RIHBsb3QpLiBFbGUgY29tcGFyYSBhIGZ1bsOnw6NvIGRlIGRpc3RyaWJ1acOnw6NvIGN1bXVsYXRpdmEgKENERikgZG9zIHZhbG9yZXMgYWp1c3RhZG9zIGRhIGZ1bsOnw6NvIGRldGVjw6fDo28gYSBkaXN0cmlidWnDp8OjbyBlbXDDrXJpY2EgZG9zIGRhZG9zIChFREYpLiAKClRhbWLDqW0gcG9kZW1vcyB1c2FyIG8gdGVzdGUgZGUgQ3JhbcOpci12b24gTWlzZXMgcGFyYSB0ZXN0YXIgc2Ugb3MgcG9udG9zIGRhIEVERiBlIGRhIENERiB0ZW0gb3JpZ2VtIG5hIG1lc21hIGRpc3RyaWJ1acOnw6NvLiBPIHRlc3RlIHVzYSBhIHNvbWEgZGUgdG9kYXMgYXMgZGlzdMOibmNpYXMgZW50cmUgdW0gcG9udG8gZSBhIGxpbmhhIHkgPSB4IHBhcmEgZm9ybWFyIGEgZXN0YXTDrXN0aWNhIGEgc2VyIHRlc3RhZGEuIFVtIHJlc3VsdGFkbyBzaWduaWZpY2F0aXZvIGZvcm5lY2UgZXZpZMOqbmNpYSBjb250cmEgYSBoaWlww7N0ZXNlIG51bGEsIHN1Z2VyaW5kbyBxdWUgbyBtb2RlbG8gbsOjbyBzZSBhanVzdGEgYmVtIGFvcyBkYWRvcy4KCmBgYHtyfQojIGFqdXN0YW5kbyB1bSBtb2RlbG8gSGFsZi1ub3JtYWwKY3V0aWFfaG4gPC0gZHMoZGF0YSA9IGN1dGlhX3RhcF9hcmFwXzE1LAogICAgICAgICAgICAgICAgIHRydW5jYXRpb24gPSAyMCwKICAgICAgICAgICAgICAgICB0cmFuc2VjdCA9ICJsaW5lIiwKICAgICAgICAgICAgICAgICBrZXkgPSAiaG4iLCAKICAgICAgICAgICAgICAgICBhZGp1c3RtZW50ID0gTlVMTCkKCiMgY29uZHV6aW5kbyBvIHRlc3RlIGRmZSBib25kYWRlZGUgYWp1c3RlIGRlIENyYW1lci12b24gTWlzZXMKZ29mX2RzKGN1dGlhX2huKQoKZ29mX2RzKGN1dGlhX2hyX3RpbWUpCmBgYAoKTyByZXN1dGxhZG8gZG8gdGVzdGUgYXBvbnRhIHF1ZSBvIG1vZGVsbyAqSGFsZi1ub3JtYWwqIGRldmUgc2VyIGRlc2NhcnRhZG8uCgpUZXN0ZXMgZGUgYm9uZGFkZSBkZSBhanVzdGUgZGUgY2hpLXF1YWRyYWRvIHPDo28gZ2VyYWRvcyB1c2FuZG8gYSBmdW7Dp8OjbyBgZ29mX2RzYCBxdWFuZG8gYXMgZGlzdMOibmNpYXMgZm9ybmVjZWlkYXMgZXN0w6NvIGNhdGVnb3JpemFkYXMuCgojIyMgU2VsZcOnw6NvIGRlIE1vZGVsb3MKClVtYSB2ZXogcXVlIHRlbW9zIHVtIGNvbmp1bnRvIGRlIG1vZGVsb3MgcGxhdXPDrXZlaXMsIHBvZGVtb3MgdXRpbGl6YXIgbyBjaXJ0w6lyaW9kZSBpbmZvcm1hw6fDo29kZSBBa2Fpa2UgKEFJQykgcGFyYSBzZWxlY2lvbmFyIGVudHJlIG9zIG1vZGVsb3MgbyBxdWUgbWVsaG9yIHNlIGFqdXN0YSBhb3MgZGFkb3MgdXRpbGl6YW5kbyBhIGZ1bsOnw6NvIGBzdW1tYXJpemVfZHNfbW9kZWxzYC4KCmBgYHtyfQojIGdlcmFuZG8gdW1hIHRhYmVsYSBkZSBzZWxlw6fDo28gZGUgbW9kZWxvcyB1c2FuZG8gQUlDCnN1bW1hcml6ZV9kc19tb2RlbHMoY3V0aWFfaG4sIGN1dGlhX2hyX3RpbWUsIGN1dGlhX2hyX3RpbWVfc2l6ZSkKYGBgCgpPIG1lbGhvciBtb2RlbG8gw6kgbyBIYXphcmQtcmF0ZSBjb20gdGVtcG8gZGUgc2Vuc28gZSB0YW1hbmhvIGRvIGdydXBvIGNvbW8gY292YXJpw6F2ZWlzLgoKIyMgRXN0aW1hbmRvIGEgYWJ1bmTDom5jaWEgZSBhIHZhcmnDom5jaWEKCiMjIyBFc3RpbWFuZG8gYWJ1bmTDom5jaWEgZSB2YXJpw6JuY2lhIG5vIFIKClBhcmEgb2J0ZXIgYSBhYnVuZMOibmNpYSBuYSByZWdpw6NvIGRlIGVzdHVkbywgcHJpbWVpcm8gY2FsY3VsYW1vcyBhIGFidW5kw6JuY2lhIG5hIMOhcmVhIGFtb3N0cmFkYSBwYXJhIG9idGVyICROX2MkIGUgZW0gc2VndWlkYSBlc2NhbG9uYW1vcyBlc3NlIHZhbG9yIHBhcmEgdG9kYSBhIMOhcmVhIGRlIGVzdHVkbyBtdWx0aXBsaWNhbmRvICROX2MkIHBlbGEgcmF6w6NvIGVudHJlIGEgw6FyZWEgYW1vc3RyYWRhIGUgYSDDoXJlYSBkYSByZWdpw6NvLiBQYXJhIGVzdGltYXIgYSBhYnVuZMOibmNpYSBuYSDDoXJlYSBhbW9zdHJhZGEsIHV0aWxpemFtb3MgYXMgZXN0aW1hdGl2YXMgZGUgcHJvYmFiaWxpZGFkZSBkZSBkZXRlY8Onw6NvIG5vIGVzdGltYWRvciBkZSBIb3J2aXR6LVRob21wc29uLgoKUXVhbmRvIGZvcm5lY2Vtb3Mgb3MgZGFkb3Mgbm8gZm9ybWF0byBjb3JyZXRvICgiZmxhdGZpbGUiKSBgZHNgIGlyw6EgYXV0b21hdGljYW1lbnRlIGNhbGN1bGFyIGFzIGVzdGltYXRpdmFzIGRlIGFidW5kw6JuY2lhIGJhc2VhZG8gbmFzIGluZm9ybWHDp8O1ZXMgZGUgYW1vc3RyYWdlbSBwcmVzZW50YSBub3MgZGFkb3MuCgpgYGB7cn0Kc3VtbWFyeShjdXRpYV9obikKYGBgCgoxLiBTdW1tYXJ5IHN0YXRpc3RpY3M6IGZvcm5lY2UgYXMgw6FyZWFzLCBhxZVlYSBkZSBhbW9zdHJhZ2VtLCBlc2ZvcsOnbywgbsO6bWVybyBkZSBvYnNlcnZhw6fDtWVzLCBuw7ptZXJvIGRlIHRyYW5zZWN0b3MsIHRheGEgZGUgZW5jb250cm8sIHNldXMgZXJyb3MgcGFkcsO1ZXMgZSBjb2VmaWNpZW50ZXMgZGUgdmFyaWHDp8OjbyBwYXJhIGNhZGEgZXN0cmF0bzsKCjIuIEFidW5kYW5jZTogZm9ybmVjZSBlc3RpbWF0aXZhcywgZXJyb3MgcGFkcsO1ZXMsIGNvZWZpY2llbnRlc2RlIHZhcmlhw6fDo28sIGludGVydmFsb3MgZGUgY29uZmlhbsOnYSBpbmZlcmlvciBlIHN1cGVyaW9yLCBncmF1cyBkZSBsaWJlcmRhZGUgcGFyYSBhIGVzdGltYXRpdmEgZGUgYWJ1bmTDom5jaWEgZGUgY2FkYSBlc3RyYXRvOwoKMy4gRGVuc2lkYWRlOiBsaXN0YSBhcyBtZXNtYXMgZXN0YXTDrXN0aWNhcyBkZSBBYnVuZGFuY2UsIHPDsyBxdWUgcGFyYSBkZW5zaWRhZGUuCgo=